package com.zy;

import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.ChatMessageDeserializer;
import dev.langchain4j.data.message.ChatMessageSerializer;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.MemoryId;
import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.store.memory.chat.ChatMemoryStore;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.time.Duration;
import java.util.List;

/**
 * @program: AI_langchain4j
 * @description: 自定义实现基于redis的chatmemory存储
 * @author: zy
 * @create: 2025-06-30 14:02
 */
public class _11_AiServiceWithPersistentChatMemory {
    //提供一个 接口
    interface Assitant{
        @SystemMessage("你是一位java专家，擅长java框架，微服务，springAI等技术.")
        String chat(@MemoryId int memoryId, @UserMessage String message);
    }

    public static void main(String[] args) {
        PersistentChatMemoryStore memoryStore=new PersistentChatMemoryStore();  // 自定义实现的chatmemory存储
        // 创建一个chatMomoryProvider对象
        ChatMemoryProvider chatMemoryProvider= memoryId-> MessageWindowChatMemory.builder()
                .id(   memoryId )
                .maxMessages(1000)
                .chatMemoryStore(   memoryStore )
                .build();

        String apiKey = System.getenv("OPEN_AI_KEY");

        OpenAiChatModel model = OpenAiChatModel.builder()
                .apiKey(apiKey)
                .modelName("deepseek-chat")
                .baseUrl(   "https://api.deepseek.com"    )    //deepseek的API地址
                .logRequests(true)
               // .logResponses(true)
                .build();
        //生成代理对象
        Assitant assistant= AiServices.builder(Assitant.class)
                .chatModel(  model )
                .chatMemoryProvider(  chatMemoryProvider )
                .build();
       System.out.println(   assistant.chat(  1, "我是张三，我今年大三，想学习java, 学习路线是什么?"     ));
        System.out.println( assistant.chat( 2, "我是李四，我的专业是汉语言文学， 想学习c, 学习路线是什么?"));
        System.out.println( assistant.chat( 1, "我已经学过了j2se, j2ee了， 想找实习，可以找实习吗?"));


    }
}

class PersistentChatMemoryStore implements ChatMemoryStore {
    private static final String REDIS_HOME="localhost";
    private static final int REDIS_PORT=6379;
    //redis是键值库，为区分数据， 设置一个key的前缀
    private static final String REDIS_KEY_PREFIX="chat:memory:";   // redis key的前缀
    private final JedisPool jedisPool;  // 连接池

    public PersistentChatMemoryStore() {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(128);  // 最大连接数
        poolConfig.setMaxIdle(128);   // 最大空闲连接数
        poolConfig.setMinIdle(16);    // 最小空闲连接数
        poolConfig.setTestOnBorrow(true);  // 连接池中的连接在被使用之前进行测试
        poolConfig.setTestOnReturn(true);
        poolConfig.setTestWhileIdle(true);
        poolConfig.setMinEvictableIdleTimeMillis(Duration.ofSeconds(60).toMillis());
        poolConfig.setTimeBetweenEvictionRunsMillis(Duration.ofSeconds(30).toMillis());
        poolConfig.setNumTestsPerEvictionRun(3);
        poolConfig.setBlockWhenExhausted(true);

        this.jedisPool = new JedisPool(poolConfig, REDIS_HOME, REDIS_PORT);
    }

    @Override
    public List<ChatMessage> getMessages(Object memoryId) {
        String key=getKey(   memoryId );
        try(  Jedis jedis=jedisPool.getResource()  ){
             String messageJson= jedis.get(key );
             if( messageJson==null || messageJson.isEmpty() ){
                 return List.of();
             }
             return ChatMessageDeserializer.messagesFromJson(messageJson);  //将redis中的json字符串反序列化为   List<ChatMessage>对象
        }
    }

    private String getKey(Object memoryId) {
        return REDIS_KEY_PREFIX + memoryId.toString();
    }

    @Override
    public void updateMessages(Object memoryId, List<ChatMessage> messages) {
        String key=getKey(   memoryId );
        try(  Jedis jedis=jedisPool.getResource()  ){
            String messageJson= ChatMessageSerializer.messagesToJson(messages);  //将   List<ChatMessage>对象序列化为json字符串
            jedis.set(key, messageJson );
        }
    }

    @Override
    public void deleteMessages(Object memoryId) {
        String key=getKey(   memoryId );
        try(  Jedis jedis=jedisPool.getResource()  ){
            jedis.del(key );
        }
    }

    //关闭联接池的方法
    public void close(){
        if(  jedisPool!=null   && !jedisPool.isClosed() ){
            jedisPool.close();
        }
    }
}
